package pers.zero.jwt.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import pers.zero.jwt.entity.UserPrinciple;
import pers.zero.jwt.spring.config.JwtConfig;

import java.util.HashMap;
import java.util.Map;

/**
 * <p><b>
 *
 * </b></p>
 * <br/>
 * 创建时间: 9/3/2019 8:34 AM
 *
 * @author Zero
 */
@Component
public class JwtClientUtil {

    private static JwtConfig jwtConfig;


    @Autowired
    private void setJwtConfig(JwtConfig config) {
        jwtConfig = config;
        SECRET = jwtConfig.secret;
    }

    /**
     * 默认 的 SECRET，根据 {@link JwtConfig#secret} 配置获取
     */
    private static String SECRET = "4e87872f-8948-4c47-8a4e-2754a7" +
            "342b3a--3ae8443b-3015-4fd3-ba40-f2f14a66287b";


    /**
     * @return token string
     */
    public static String makeToken(UserPrinciple principle) {

        if (principle.getTimestamp() == 0L) {
            throw new RuntimeException("principle timestamp can not be null!!!!\n" +
                    "登录信息必须设置 timestamp !!!");
        }

        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        Map<String, Object> headerClaims = new HashMap<>(5);
        return JWT.create()
                .withHeader(headerClaims)
                .withClaim("uid", principle.getUid())
                .withClaim("name", principle.getName())
                .withClaim("roleId", principle.getRoleId())
                .withClaim("isMobile",principle.isMobile())
                .withClaim("timestamp", principle.getTimestamp())
                .sign(algorithm);
    }

    /**
     * 返回 的  id 代表 登录的客服用户的 id
     *
     * @param token 加密后的 token
     * @return {@code Map<String,Object>}
     */
    public static UserPrinciple decodeToken(String token) {
        UserPrinciple user = null;
        try {

            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .build(); //Reusable verifier instance
            DecodedJWT jwt = verifier.verify(token);
            /*
            *   uid
                name
                roleId
                region
                level
                timestamp
            * */
            Integer uid = jwt.getClaim("uid").as(Integer.class);
            String name = jwt.getClaim("name").as(String.class);
            Integer roleId = jwt.getClaim("roleId").as(Integer.class);


            long timestamp = jwt.getClaim("timestamp").as(Long.class);
            Boolean isMobile = jwt.getClaim("isMobile").asBoolean();
            if(isMobile == null){
                isMobile = false;
            }

            user = new UserPrinciple();

            user.setUid(uid);
            user.setName(name);
            user.setRoleId(roleId);
            user.setMobile(isMobile);

            user.setTimestamp(timestamp);

        } catch (Exception ignored) {
            // ignore exception
        }

        return user;
    }
}
